home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Contributions / Haage_&_Partner / Storm-Projects / NDKExamples1 / intuition / relspecial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-04-16  |  7.5 KB  |  315 lines

  1. /*
  2.  * relspecial.c - shows special gadget relativity
  3.  *
  4.  * (c) Copyright 1992-1996 Amiga International, Inc. All rights reserved.
  5.  *
  6.  * This software is provided as-is and is subject to change; no warranties
  7.  * are made.  All use is at your own risk.  No liability or responsibility
  8.  * is assumed.
  9.  *
  10.  * Special gadget relativity allows a gadget to arbitrarily resize
  11.  * itself whenever the window changes size.  This is a complete superset
  12.  * of the functionality of the old GRELWIDTH, GRELRIGHT, etc., features.
  13.  * This example shows a subclass of gadgetclass whose imagery comes
  14.  * from frameiclass.  This gadget's property is that it is always half
  15.  * the size of its domain, and centered within it.  That is, it's always
  16.  * half as wide and half as tall as the inner area of its window, and
  17.  * centered within that area.
  18.  */
  19.  
  20. #include <intuition/intuition.h>
  21. #include <intuition/gadgetclass.h>
  22. #include <intuition/imageclass.h>
  23. #include <intuition/cghooks.h>
  24. #include <intuition/classes.h>
  25. #include <intuition/classusr.h>
  26.  
  27. #include <clib/alib_protos.h>
  28. #include <clib/exec_protos.h>
  29. #include <clib/graphics_protos.h>
  30. #include <clib/intuition_protos.h>
  31.  
  32. #include <stdio.h>
  33.  
  34. struct Library *GfxBase = NULL;
  35. struct Library *IntuitionBase = NULL;
  36. struct Window *win = NULL;
  37. struct Gadget *gad = NULL;
  38. Class *specialrelclass = NULL;
  39.  
  40. Class *initSpecialRelClass(void);
  41.  
  42. __saveds ULONG dispatchSpecialRel(register __a0 Class *cl,
  43.                                              register __a2 Object *o, 
  44.                                              register __a1 Msg msg );
  45.  
  46. void renderSpecialRel(struct Gadget *gad, 
  47.                              struct RastPort *rp,
  48.                              struct GadgetInfo *gi );
  49.  
  50. void layoutSpecialRel(struct Gadget *gad, 
  51.                              struct GadgetInfo *gi,
  52.                              ULONG initial );
  53.  
  54. LONG handleSpecialRel(struct Gadget *gad, 
  55.                              struct gpInput *msg );
  56.  
  57.  
  58. void main(void)
  59. {
  60.     if ( GfxBase = OpenLibrary("graphics.library",39) )
  61.     {
  62.     if ( IntuitionBase = OpenLibrary("intuition.library",39) )
  63.     {
  64.         if ( specialrelclass = initSpecialRelClass() )
  65.         {
  66.         if ( gad = NewObject( specialrelclass, NULL,
  67.             GA_Left, 20,
  68.             GA_Top, 20,
  69.             GA_Width, 20,
  70.             GA_Height, 20,
  71.             GA_RelVerify, TRUE,
  72.             GA_Immediate, TRUE,
  73.             TAG_DONE ) )
  74.         {
  75.             if ( win = OpenWindowTags( NULL,
  76.             WA_Title, "Special Relativity Demo",
  77.             WA_CloseGadget, TRUE,
  78.             WA_DepthGadget, TRUE,
  79.             WA_DragBar, TRUE,
  80.             WA_SizeGadget, TRUE,
  81.             WA_Gadgets, gad,
  82.             WA_Activate, TRUE,
  83.             WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_GADGETDOWN | IDCMP_GADGETUP,
  84.             WA_Width, 150,
  85.             WA_Height, 150,
  86.             WA_MinWidth, 50,
  87.             WA_MinHeight, 50,
  88.             WA_MaxWidth, ~0,
  89.             WA_MaxHeight, ~0,
  90.             WA_NoCareRefresh, TRUE,
  91.             TAG_DONE ) )
  92.             {
  93.             BOOL terminated = FALSE;
  94.             struct IntuiMessage *imsg;
  95.  
  96.             while ( !terminated )
  97.             {
  98.                 Wait( 1 << win->UserPort->mp_SigBit );
  99.                 while ( imsg = (struct IntuiMessage *)GetMsg( win->UserPort ) )
  100.                 {
  101.                 switch ( imsg->Class )
  102.                 {
  103.                 case IDCMP_CLOSEWINDOW:
  104.                     terminated = TRUE;
  105.                     break;
  106.  
  107.                 case IDCMP_GADGETUP:
  108.                     printf("Gadget up\n");
  109.                     break;
  110.  
  111.                 case IDCMP_GADGETDOWN:
  112.                     printf("Gadget down\n");
  113.                     break;
  114.                 }
  115.                 ReplyMsg( (struct Message *)imsg );
  116.                 }
  117.             }
  118.             CloseWindow( win );
  119.             }
  120.             DisposeObject( gad );
  121.         }
  122.         FreeClass( specialrelclass );
  123.         }
  124.         CloseLibrary( IntuitionBase );
  125.     }
  126.     CloseLibrary( GfxBase );
  127.     }
  128. }
  129.  
  130.  
  131. /* initSpecialRelClass()
  132.  *
  133.  * Initialize a simple private subclass of gadgetclass that
  134.  * knows about GM_LAYOUT.
  135.  *
  136.  */
  137.  
  138. Class *initSpecialRelClass( void )
  139. {
  140.     Class *cl;
  141.  
  142.     /* Create a private class: */
  143.     if ( cl = MakeClass( NULL, "gadgetclass", NULL, 0, 0 ) )
  144.     {
  145.     cl->cl_Dispatcher.h_SubEntry = NULL;
  146.     cl->cl_Dispatcher.h_Entry = (HOOKFUNC)dispatchSpecialRel;
  147.     cl->cl_Dispatcher.h_Data = NULL;
  148.     }
  149.     return ( cl );
  150. }
  151.  
  152. /* dispatchSpecialRel()
  153.  *
  154.  * boopsi dispatcher for the special relativity class.
  155.  *
  156.  */
  157.  
  158. __saveds ULONG
  159. dispatchSpecialRel(     register __a0 Class *cl,
  160.                             register __a2 Object *o,
  161.                             register __a1 Msg msg )
  162. {
  163.     ULONG retval = 1;
  164.     Object *newobj;
  165.  
  166.     geta4();
  167.  
  168.     switch ( msg->MethodID )
  169.     {
  170.     case OM_NEW:
  171.     if ( retval = (ULONG)(newobj = (Object *) DoSuperMethodA( cl, o, msg )) )
  172.     {
  173.         /* Set special relativity */
  174.         ((struct Gadget *)newobj)->Flags |= GFLG_RELSPECIAL;
  175.         /* Attempt to allocate a frame.  If I can't, then
  176.          * delete myself and fail.
  177.          */
  178.         if ( ! ( ((struct Gadget *)newobj)->GadgetRender =
  179.         NewObject( NULL, "frameiclass", TAG_DONE ) ) )
  180.         {
  181.         CoerceMethod( cl, newobj, OM_DISPOSE );
  182.         retval = NULL;
  183.         }
  184.     }
  185.     break;
  186.  
  187.     case GM_LAYOUT:
  188.     layoutSpecialRel( (struct Gadget *)o, ((struct gpLayout *)msg)->gpl_GInfo,
  189.         ((struct gpLayout *)msg)->gpl_Initial );
  190.     break;
  191.  
  192.     case GM_RENDER:
  193.     renderSpecialRel( (struct Gadget *)o, ((struct gpRender *) msg)->gpr_RPort,
  194.         ((struct gpRender *) msg)->gpr_GInfo );
  195.     break;
  196.  
  197.     case GM_GOACTIVE:
  198.     return( GMR_MEACTIVE );
  199.     break;
  200.  
  201.     case GM_HANDLEINPUT:
  202.     retval = handleSpecialRel( (struct Gadget *)o, (struct gpInput *)msg );
  203.     break;
  204.  
  205.     case OM_DISPOSE:
  206.     DisposeObject( ((struct Gadget *)o)->GadgetRender );
  207.     /* fall through to default */
  208.     default:
  209.     retval = (ULONG) DoSuperMethodA( cl, o, msg );
  210.     }
  211.     return( retval );
  212. }
  213.  
  214.  
  215. /* renderSpecialRel()
  216.  *
  217.  * Simple routine to draw my imagery based on my selected state.
  218.  *
  219.  */
  220. void
  221. renderSpecialRel( struct Gadget *gad, struct RastPort *rp, struct GadgetInfo *gi )
  222. {
  223.     DrawImageState( rp, gad->GadgetRender, gad->LeftEdge, gad->TopEdge,
  224.     (gad->Flags & GFLG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
  225.     gi ? gi->gi_DrInfo : NULL );
  226. }
  227.  
  228.  
  229. /* layoutSpecialRel()
  230.  *
  231.  * Lay myself out based on my domain dimensions.  Refigure my own size,
  232.  * then inform my image of the size change.
  233.  *
  234.  */
  235. void
  236. layoutSpecialRel( struct Gadget *gad, struct GadgetInfo *gi, ULONG initial )
  237. {
  238.     if ( gi->gi_Requester )
  239.     {
  240.     /* Center it within the requester */
  241.     gad->Width = gi->gi_Domain.Width / 2;
  242.     gad->Height = gi->gi_Domain.Height / 2;
  243.     gad->LeftEdge = gad->Width / 2;
  244.     gad->TopEdge = gad->Height / 2;
  245.     }
  246.     else
  247.     {
  248.     /* Center it within the window, after accounting for
  249.      * the window borders
  250.      */
  251.     gad->Width = ( gi->gi_Domain.Width -
  252.         gi->gi_Window->BorderLeft - gi->gi_Window->BorderRight ) / 2;
  253.     gad->Height = ( gi->gi_Domain.Height -
  254.         gi->gi_Window->BorderTop - gi->gi_Window->BorderBottom ) / 2;
  255.     gad->LeftEdge = ( gad->Width / 2 ) + gi->gi_Window->BorderLeft;
  256.     gad->TopEdge = ( gad->Height / 2 ) + gi->gi_Window->BorderTop;
  257.     }
  258.     SetAttrs( gad->GadgetRender,
  259.     IA_Width, gad->Width,
  260.     IA_Height, gad->Height,
  261.     TAG_DONE );
  262. }
  263.  
  264.  
  265. /* handleSpecialRel()
  266.  *
  267.  * Routine to handle input to the gadget.  Behaves like a basic
  268.  * hit-select gadget.
  269.  *
  270.  */
  271. LONG
  272. handleSpecialRel( struct Gadget *gad, struct gpInput *msg )
  273. {
  274.     WORD selected = 0;
  275.     struct RastPort *rp;
  276.     LONG retval = GMR_MEACTIVE;
  277.  
  278.     /* Could send IM_HITTEST to image instead */
  279.     if ( ( msg->gpi_Mouse.X >= 0 ) &&
  280.     ( msg->gpi_Mouse.X < gad->Width ) &&
  281.     ( msg->gpi_Mouse.Y >= 0 ) &&
  282.     ( msg->gpi_Mouse.Y < gad->Height ) )
  283.     {
  284.     selected = GFLG_SELECTED;
  285.     }
  286.  
  287.     if ((msg->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE) &&
  288.     (msg->gpi_IEvent->ie_Code == SELECTUP))
  289.     {
  290.     /* gadgetup, time to go */
  291.     if ( selected )
  292.     {
  293.         retval = GMR_NOREUSE | GMR_VERIFY;
  294.     }
  295.     else
  296.     {
  297.         retval = GMR_NOREUSE;
  298.     }
  299.     /* and unselect the gadget on our way out... */
  300.     selected = 0;
  301.     }
  302.  
  303.     if ( ( gad->Flags & GFLG_SELECTED ) != selected )
  304.     {
  305.     gad->Flags ^= GFLG_SELECTED;
  306.     if ( rp = ObtainGIRPort( msg->gpi_GInfo ) )
  307.     {
  308.         DoMethod( (Object *)gad, GM_RENDER, msg->gpi_GInfo, rp, GREDRAW_UPDATE );
  309.         ReleaseGIRPort( rp );
  310.     }
  311.     }
  312.  
  313.     return( retval );
  314. }
  315.